package com.zoweunion.mechanic.service.order.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.druid.util.StringUtils;
import com.zoweunion.mechanic.dao.*;
import com.zoweunion.mechanic.dao.app.AppDao;
import com.zoweunion.mechanic.dao.order.KFOrderDao;
import com.zoweunion.mechanic.entity.AuxiliaryRepairMenBean;
import com.zoweunion.mechanic.entity.MainRepairMenBean;
import com.zoweunion.mechanic.entity.OrderExportBean;
import com.zoweunion.mechanic.entity.RepairBean;
import com.zoweunion.mechanic.entity.vo.TSBrOrderDetailRepairmanVO;
import com.zoweunion.mechanic.entity.vo.TSSsUserVO;
import com.zoweunion.mechanic.entity.vo.TSSsWarehouseRegionVO;
import com.zoweunion.mechanic.entity.vo.TSSsWarehouselocationVO;
import com.zoweunion.mechanic.model.MyConfig;
import com.zoweunion.mechanic.model.User;
import com.zoweunion.mechanic.service.app.AppService;
import com.zoweunion.mechanic.service.app.OrderService;
import com.zoweunion.mechanic.service.app.ToolViewBoardService;
import com.zoweunion.mechanic.service.base.BaseService;
import com.zoweunion.mechanic.service.base.UserService;
import com.zoweunion.mechanic.service.impl.TSSsUserServiceImpl;
import com.zoweunion.mechanic.service.impl.TSTtOrderServiceImpl;
import com.zoweunion.mechanic.service.order.KFOrderService;
import com.zoweunion.mechanic.util.*;
import com.zoweunion.mechanic.util.constants.Constants;
import com.zoweunion.mechanic.util.constants.PushConstants;
import com.zoweunion.mechanic.util.entity.OrderBean;
import com.zoweunion.mechanic.util.entity.OrderCheck;
import com.zoweunion.mechanic.util.gaode.AddressGEOUtil;
import jodd.util.StringUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * 客服工单业务类
 *
 * @author Administrator
 */
@Service
@Transactional
@SuppressWarnings("unchecked")
public class KFOrderServiceImpl extends BaseService implements KFOrderService {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserService userService;

    @Autowired
    private TSSsWarehouselocationMapper warehouseLocationDao;

    @Autowired
    private TSTtOrderServiceImpl tsTtOrderService;

    @Autowired
    private TSSsUserServiceImpl tsSsUserService;

    @Autowired
    private TSBrOrderDetailFaultMapper orderDetailFaultDao;

    @Autowired
    private TSsDictionariesFaultMapper dictionariesFaultDao;

    @Autowired
    private TSBrOrderDetailRepairmanMapper repairmanDao;

    @Autowired
    private TSSsWarehouseRegionMapper warehouseRegionDao;
    @Autowired
    private KFOrderDao kFOrderDao;
    @Autowired
    private AppService appService;
    @Autowired
    private AppDao appDao;
    @Autowired
    private MyConfig myConfig;
    @Resource(name = "cachedThreadPool")
    private ExecutorService cachedThreadPool;
    @Autowired
    private WebSocketPushUtil webSocketPushUtil;
    @Autowired
    private JiGuangPushUtil jiGuangPushUtil;
    @Autowired
    private AddressGEOUtil addressGEOUtil;
    @Autowired
    private ToolViewBoardService toolViewBoardService;
    @Autowired
    private OrderService orderService;

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> listByStatus(Map<String, Object> reqMap) {
        // 1.设置分页的limit和offset
        Map<String, Object> pageMap = Page.appPage(reqMap.get("pageSize").toString(),
                reqMap.get("currentPage").toString());
        reqMap.put("pageSize", pageMap.get("limit"));
        reqMap.put("currentPage", pageMap.get("offset"));
        int limit = Integer.valueOf(pageMap.get("limit").toString());

        // 2.查询总记录数
        int total = kFOrderDao.countBycondition(reqMap);

        // 2执行分页查询
        List<Map<String, Object>> orderList = kFOrderDao.listByStatus(reqMap);



        // 4 根据工单id关联查询故障列表和工单图片
        if (total > 0||total ==0) {
            orderList.forEach(orderMap -> {
                orderMap.put("order_id", orderMap.get("id"));
                List<Map<String, Object>> orderId = kFOrderDao.getOrderFaultByOrderId(orderMap);
                List<Map<String, Object>> mapList =
                        toolViewBoardService.listByFault(orderId, reqMap.get("s_id").toString());
                orderMap.put("faultInfo",mapList);
                // 工单图片
                List<Map<String, Object>> imgList = appDao.findOrderImg(orderMap);
                orderMap.put("img_info", imgList);
            });
        }
        // 5根据工单id关联查询修工
        if (total > 0||total ==0) {
            orderList.forEach(orderMap -> {
                orderMap.put("order_id", orderMap.get("id"));
                orderMap.put("repairmanInfo", kFOrderDao.getOrderRepairmanByOrderId(orderMap));
            });
        }

        // 查询修工收取现金时间
        if (total > 0||total ==0) {
            orderList.forEach(orderMap -> {
                orderMap.put("order_id", orderMap.get("id"));
                orderMap.put("getMoneyTime", kFOrderDao.getRepairMoneyTime(orderMap));
            });
        }

        // 6包装结果集 总条数 总页数 数据集
        HashMap<String, Object> resultMap = new HashMap<String, Object>();
        int pages = (total + limit - 1) / limit;// 总页数 需要有余进一
        // 获取当前登入用户
        User user = (User) reqMap.get("user");
        // 获取当前用户的角色
        String r_id = user.getR_id();
        // 将符合地域要求的工单分发给对应的客服
        // 判断当前登入用户是否 为客服
        if (r_id.equals(Constants.ROLE_KF)) {
            // 当前客服所负责的区域
            String area = user.getArea() == null ? "" : user.getArea();
            if (!"".equals(area)) {
                List<Map<String, Object>> resultList = orderList.stream().filter(map -> {
                    if (map.get("area") == null) {
                        return true;
                    }
                    if (area.contains(map.get("area").toString())) {
                        return true;
                    } else {
                        return false;
                    }
                    // 判断该工单所在的地域属于哪一类省份(按省,自治区,直辖市分类)
//                    if (map.get("area").toString().contains("省")) {
//                        int index = map.get("area").toString().indexOf("省");
//                        // 截取该工单所对应的省份
//                        String province = map.get("area").toString().substring(0, index + 1);
//                        // 查看该工单所对应的大区
//                        String region_name = kFOrderDao.getRegionByProvince(province);
//                        // 若客服所服务的地域包含该工单所在的省份,则返回true,否则返回false
//                        if (area.contains(region_name)) {
//                            return true;
//                        } else {
//                            return false;
//                        }
//                    } else if (map.get("area").toString().contains("区")) {
//                        int index = map.get("area").toString().indexOf("区");
//                        String province = map.get("area").toString().substring(0, index + 1);
//                        String region_name = kFOrderDao.getRegionByProvince(province);
//                        if (area.contains(region_name)) {
//                            return true;
//                        } else {
//                            return false;
//                        }
//                    } else {
//                        int index = map.get("area").toString().indexOf("市");
//                        String province = map.get("area").toString().substring(0, index + 1);
//                        String region_name = kFOrderDao.getRegionByProvince(province);
//                        if (area.contains(region_name)) {
//                            return true;
//                        } else {
//                            return false;
//                        }
//                    }
                }).collect(Collectors.toCollection(ArrayList::new));
                resultMap.put("total", total);
                resultMap.put("pages", pages);
                resultMap.put("list", resultList);
            } else {
                resultMap.put("total", total);
                resultMap.put("pages", pages);
                resultMap.put("list", orderList);
            }
        } else {
            resultMap.put("total", total);
            resultMap.put("pages", pages);
            resultMap.put("list", orderList);
        }
        return resultMap;
    }

    @Override
    public List<OrderExportBean> exportHistoryList(Map<String, Object> params) {
        List<OrderExportBean> orderExportList = new ArrayList<>();
        List<OrderBean> orderList = new ArrayList<>();
        orderList = kFOrderDao.getOrderList(params);
        List<OrderBean> resultMap = new ArrayList<>();
        // 获取当前登入用户
        User user = (User) params.get("user");
        // 获取当前用户的角色
        String r_id = user.getR_id();
        if (r_id.equals(Constants.ROLE_KF)) {
            // 当前客服所负责的区域
            String area = user.getArea() == null ? "" : user.getArea();
            if (!"".equals(area)) {
                List<OrderBean> resultList = orderList.stream().filter(map -> {
                    if (map.getArea() == null) {
                        return true;
                    }
                    if (area.contains(map.getArea())) {
                        return true;
                    } else {
                        return false;
                    }
                }).collect(Collectors.toCollection(ArrayList::new));
                resultMap = resultList;
            } else {
                resultMap = orderList;
            }
        } else {
            resultMap = orderList;
        }
        for(OrderBean order : resultMap) {
            List<RepairBean> repairList = new ArrayList<>();
            List<MainRepairMenBean> mainRepairMenList = new ArrayList<>();
            List<AuxiliaryRepairMenBean> auxiliaryRepairMenList = new ArrayList<>();
            String orderId = order.getOrderId();
            params.put("order_id", orderId);
            final float[] repairPay = new float[1];
            List<Map<String, Object>> repairPays = kFOrderDao.getRepairPay(params);
            repairPays.parallelStream().forEach(item -> {
                if (item !=null && !item.toString().equals("")) {
                    if (item.get("quantity") != null && !item.get("quantity").equals("")
                            && item.get("price") != null && !item.get("price").equals("")) {
                        int quantity = Integer.valueOf(item.get("quantity").toString());
                        float price = Float.parseFloat(item.get("price").toString());
                        float repairPay1 = quantity * price;
                        repairPay[0] = repairPay[0] + repairPay1;
                    }
                }
            });
            RepairBean repair = kFOrderDao.getRepair(params);
            if (repair!=null && !repair.equals("")) {
                if (repair.getTotalPay() != null && !repair.getTotalPay().equals("")) {
                    float totalPay = Float.parseFloat(repair.getTotalPay());
                    float partsPay = totalPay - repairPay[0];
                    if(partsPay >= 0) {
                        repair.setRepairPay(String.valueOf(repairPay[0]));
                        repair.setPartsPay(String.valueOf(partsPay));
                    } else {
                        repair.setRepairPay(String.valueOf(repairPay[0]));
                        repair.setPartsPay(String.valueOf(0));
                    }
                    repairList.add(repair);
                    String repairPer = "";
                    String partsPer = "";
                    MainRepairMenBean mainRepairMen = kFOrderDao.getMainRepairMen(params);
                    if (mainRepairMen != null && !mainRepairMen.equals("")) {
                        if (totalPay > 0 && repairPay[0] <= totalPay && repairPay[0] >= 0) {
                            repairPer = NumberFormat.getPercentInstance().format(repairPay[0] / totalPay);
                        } else {
                            repairPer = NumberFormat.getPercentInstance().format(0);
                        }
                        if (totalPay > 0 && partsPay <= totalPay && partsPay >= 0) {
                            partsPer = NumberFormat.getPercentInstance().format(partsPay / totalPay);
                        } else {
                            partsPer = NumberFormat.getPercentInstance().format(0);
                        }
                        mainRepairMen.setRepairPay(String.valueOf(repairPay[0]));
                        mainRepairMen.setPartsPay(String.valueOf(partsPay));
                        mainRepairMen.setRepairPer(repairPer);
                        mainRepairMen.setPartsPer(partsPer);
                        mainRepairMenList.add(mainRepairMen);
                        AuxiliaryRepairMenBean auxiliaryRepairMen = kFOrderDao.getAuxiliaryRepairMen(params);
                        if (auxiliaryRepairMen != null && !auxiliaryRepairMen.equals("")) {
                            auxiliaryRepairMen.setRepairPay(String.valueOf(repairPay[0]));
                            auxiliaryRepairMen.setPartsPay(String.valueOf(partsPay));
                            auxiliaryRepairMen.setRepairPer(repairPer);
                            auxiliaryRepairMen.setPartsPer(partsPer);
                            auxiliaryRepairMenList.add(auxiliaryRepairMen);
                            orderExportList.add(OrderExportBean.builder()
                                    .repair(repairList)
                                    .mainRepairMen(mainRepairMenList)
                                    .auxiliaryRepairMen(auxiliaryRepairMenList)
                                    .build());
                        } else {
                            orderExportList.add(OrderExportBean.builder()
                                    .repair(repairList)
                                    .mainRepairMen(mainRepairMenList)
                                    .build());
                        }
                    } else {
                        orderExportList.add(OrderExportBean.builder()
                                .repair(repairList)
                                .build());
                    }
                }
            }
        }
        return orderExportList;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> getfaultList(Map<String, Object> reqMap) {
        List<Map<String, Object>> maps = kFOrderDao.getfaultList(reqMap);
        return toolViewBoardService.listByFault(maps,reqMap.get("s_id").toString());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrder(Map<String, Object> reqMap) throws MyException {
        int result = 0;
        // 1.创建主工单
        // 生成工单主键
        String orderId = UuidUtil.get32UUID();
        reqMap.put("order_id", orderId);
        // 生成工单编号
        reqMap.put("order_no", Tool.markOrderNo("P", reqMap.get("order_type").toString()));
        // 状态为待听诊
        reqMap.put("order_status", Constants.ORDER_STATUS_DTZ);
        reqMap.put("u_s_id", reqMap.get("current_user_id"));
        // 通过区域号查询完整区域地址，并且和address拼接
        Map<String,Object> regionNameMap = appDao.getRegionAddressByAreaNumber(reqMap.get("area").toString());
        reqMap.put("address", regionNameMap.get("address") + reqMap.get("address").toString());
        // 获取经纬度
        Map<String, String> geoMap = addressGEOUtil.geo(reqMap.get("address").toString(), regionNameMap.get("city").toString());
        reqMap.put("longitude", geoMap.get("longitude"));
        reqMap.put("latitude", geoMap.get("latitude"));
        // 创建主工单
        result += kFOrderDao.createOrder(reqMap);
//        List<Map<String, Object>> kfList = null;
//        if (reqMap.containsKey("area") && !reqMap.get("area").equals("")) {
//            kfList = appDao.findUserByRAreaCode(reqMap);
//            if (null == kfList && kfList.size() == 0) {
//                kfList = appDao.findUserByRid(reqMap);
//            }
//        } else {
//            kfList = appDao.findUserByRid(reqMap);
//        }

        // 2根据主工单类型创建工单故障明细
        List<Map<String, Object>> faultList = (List<Map<String, Object>>) reqMap.get("faultList");
        if (faultList != null && faultList.size() > 0) {
            for (Map<String, Object> map : faultList) {
                map.put("order_fault_id", UuidUtil.get32UUID());
                map.put("current_user_id", reqMap.get("current_user_id"));
                map.put("order_id", reqMap.get("order_id"));
                map.put("s_id", reqMap.get("s_id"));
                // 创建工单故障明细
                result += kFOrderDao.createOrderFault(map);
            }
        }
        // 对含有保养套餐的创建相应配件
        if ("2".equals(reqMap.get("order_type").toString()) || "3".equals(reqMap.get("order_type").toString())) {
            appService.createOrderDetailParts(reqMap.get("m_id"), reqMap.get("current_user_id").toString(), reqMap.get("order_id").toString());
        }

        // 3 创建工单明细
        reqMap.put("order_detail_id", UuidUtil.get32UUID());
        result += kFOrderDao.createOrderDetail(reqMap);
        // 获取听诊人推送工单
        reqMap.put("code", "10000");
        reqMap.put("type", "3");
        reqMap.put("msg", "客服已经受理完成,请尽快听诊!");
        webSocketPushUtil.websocketPush(reqMap, reqMap.get("u_t_id").toString());

        // 创建工单修工出工记录表
        reqMap.put("record_id",UuidUtil.get32UUID());
        appDao.repairLocationRecord(reqMap);

        //pc端客服接单插入绩效考核
        try {
            //先获取所有角色为客服的列表
            List<Map<String, Object>> kfList = null;
//		String area = reqMap.get("area").toString();
            // 最好传code 不然传区名不外加其它东西
            if (reqMap.containsKey("area") && !reqMap.get("area").toString().equals("")) {
                kfList = appDao.findUserByRAreaName(reqMap);
                if (null == kfList || kfList.size() == 0) {
                    kfList = appDao.findUserByRid(reqMap);
                }
            } else {
                kfList = appDao.findUserByRid(reqMap);
            }
//		List<Map<String,Object>> kfList = appDao.findUserByRid(reqMap);
            // 过滤所有符合区域的客服，并求出所有客服的id
            List<String> kfIdList = kfList.parallelStream().filter(item -> {
//			int index = item.get("area").toString().indexOf("大区");
//			if (item.get("area").toString().substring(index).equals(area)){
                return true;
//			}else {
////				return  false;
////			}
            }).map(item -> {
                return item.get("id").toString();
            }).collect(Collectors.toCollection(ArrayList::new));

            //记录客服考核统计
            orderService.insertOrderCheckByKf(OrderCheck.builder()
                    .orderId(reqMap.get("order_id").toString())
                    .orderNo(reqMap.get("order_no").toString())
                    .userIds(kfIdList)
                    .roleType(Constants.ROLE_KF)
                    .checkType(Constants.ORDER_CHECK_KF_RESPONSE)
                    .isTakeOrder(0)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //客服创建工单的同时 指派听诊 开始听诊的绩效考核
        if (Integer.valueOf(reqMap.get("order_status").toString())==3){
            try {
                OrderCheck checkByOrderId = orderService.selectCheckByOrderId(reqMap.get("order_id").toString(),
                        reqMap.get("u_s_id").toString(),Constants.ORDER_CHECK_KF_RESPONSE);
                if (checkByOrderId!=null&&checkByOrderId.getEndTime()==null){
                    orderService.updateKfEndTimeList(checkByOrderId.getId());
                }
                String uId = reqMap.get("u_s_id").toString();
                OrderCheck checkByOrderId1 = orderService.selectCheckByOrderId(reqMap.get("order_id").toString(), uId,
                        Constants.ORDER_CHECK_KF_RESPONSE);
                orderService.updateKfByOrderId(OrderCheck.builder()
                        .id(checkByOrderId1.getId())
                        .orderId(reqMap.get("order_id").toString())
                        .isTakeOrder(1)
                        .build());
                //插入听诊绩效考核
                String tId = reqMap.get("u_t_id").toString();
                orderService.insertTzOrderCheck(OrderCheck.builder()
                        .orderId(reqMap.get("order_id").toString())
                        .orderNo(checkByOrderId1.getOrderNo())
                        .userId(tId)
                        .roleType(Constants.ROLE_TZ)
                        .orderCreateTime(checkByOrderId1.getOrderCreateTime())
                        .checkType(Constants.ORDER_CHECK_TZ_RESPONSE)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if(result>0){
            return orderId;
        }else{
            return "";
        }

//        return result;
    }


    /**
     * 自动分配听诊和修工
     * @param reqMap
     * @return
     */
    @Override
    public String autoGetOrderUserId(Map<String, Object> reqMap) {

        // 要查询列表的roleId
        String searchRoleId = reqMap.get("searchRoleId").toString();
        // 当前用户roleId
        String currentRoleId = reqMap.get("currentRoleId").toString();
        String currentUserId = reqMap.get("current_user_id").toString();
        String sId = reqMap.get("s_id").toString();

        // 如果是听诊
        if(Constants.ROLE_TZ.equals(searchRoleId)){

            String searchType = "insideTZ";
            reqMap.put("search_type",searchType);

            // 获取当前用户的管辖区域, insideTZ-听诊 insideXG-修工，如果是管理员，就传空
            if ("insideTZ".equals(searchType) || "insideXG".equals(searchType)) {
                reqMap.put("precinctRegions", String.join(",", appService.getPrecinctRegionNumbers("7".equals(currentRoleId) ? "" : currentUserId, sId)));
            }

            // 获取相关的听诊
            List<Map<String, Object>> userList = userService.getUser(reqMap);
            if (null == userList) {
               return "";
            }

            // 故障匹配度
            Map<String,Object>  matchUserMap = new HashMap<>();

            // 获取人员的擅长
            for (Map<String, Object> user : userList) {

                if (user.get("goodatdic_id") == null || user.get("goodatdic_id") == "") {
                    continue;
                }

                String userId = user.get("id").toString();
                String goodatdicId = user.get("goodatdic_id").toString();

                if(StringUtil.isNotBlank(goodatdicId)){

                    String[] goodatdicArray = StringUtil.split(goodatdicId, ",");

                    // 匹配程度
                    Integer matchDegree = 0;

                    // 获取工单的故障类型,这里有多个
                    // 根据order_id查询错误信息,工单故障错误与擅长匹配,这里获取到的是二级分类,但要匹配的是一级分类
                    List<Map<String, Object>> orderFaultList = kFOrderDao.getOrderFaultByOrderId(reqMap);
                    if (orderFaultList.size() > 0) {
                        for (Map<String, Object> fault : orderFaultList) {
                            for (String goodat : goodatdicArray) {
                                if (goodat.equals(fault.get("parent_id"))) {
                                    // 匹配上匹配度+1
                                    matchDegree++;
                                }
                            }
                        }
                    }

                    matchUserMap.put(userId, matchDegree);
                }

            }


            // 判断是否有匹配的人员者,如果只有一个就直接返回，如果匹配多个的话，后续还需要匹配所分配的工单量
            if(matchUserMap.size()>0){

                if(matchUserMap.size() == 1){
                    // 如果只有一个匹配的就返回userId
                    return matchUserMap.keySet().toArray()[0].toString();
                }else{
                    // 找出最大匹配度,如果只有一个直接返回，多个匹配工单量
                    String[] maxMatchUserArray = FunUtil.getMapKeysWithMaxValue(matchUserMap);
                    if(maxMatchUserArray.length == 1){
                        return maxMatchUserArray[0];
                    }else{
                        // 匹配听诊手上的工单量
                        return getMinOrderUserId(maxMatchUserArray,searchRoleId);
                    }
                }

            }else{
                // 没有匹配上的就查看每个修改的所分配的工单量，返回量最少的那个userId
                String[] userIdArray = userList.stream()
                        .map(user -> user.get("id").toString())
                        .toArray(String[]::new);

                return getMinOrderUserId(userIdArray,searchRoleId);
            }
        }else{

            return "";
        }
    }



    /**
     * 自动分配修工
     * @param reqMap
     * @return
     */
    public String autoGetXgUserId(Map<String, Object> reqMap) {

        // 要查询列表的roleId
        String searchRoleId = reqMap.get("searchRoleId").toString();
        // 当前用户roleId
        String currentRoleId = reqMap.get("currentRoleId").toString();
        String currentUserId = reqMap.get("current_user_id").toString();
        String sId = reqMap.get("s_id").toString();

        // 如果要分配的是修工
        if(Constants.ROLE_XG.equals(searchRoleId)){

            String searchType = "insideXG";
            reqMap.put("search_type",searchType);

            // 获取当前用户的管辖区域, insideTZ-听诊 insideXG-修工，如果是管理员，就传空
//            if ("insideTZ".equals(searchType) || "insideXG".equals(searchType)) {
//                reqMap.put("precinctRegions", String.join(",", appService.getPrecinctRegionNumbers("7".equals(currentRoleId) ? "" : currentUserId, sId)));
//            }

            // 获取相关的修工
            List<Map<String, Object>> userList = userService.getUser(reqMap);
            if (null == userList) {
               return "";
            }

            // 根据工单id查询工单信息
            Map<String, Object> orderInfoMap = appDao.findOrderInfoById(reqMap);

            // 如果是第二次返修,自动分配
            if(orderInfoMap.get("return_repair").equals(2)){
                // 获取原修工
                Map<String,Object> repairManMap = new HashMap<>();
                repairManMap.put("orderId",reqMap.get("order_id"));
                repairManMap.put("delete_flag",1);

                List<TSBrOrderDetailRepairmanVO> repairmanVOList = repairmanDao.findByCondition(repairManMap);
                if(repairmanVOList.size()>0){
                    // 去除原修工
                    Iterator<Map<String, Object>> iterator = userList.iterator();
                    while(iterator.hasNext()){
                        Map<String, Object> user = iterator.next();
                        for(TSBrOrderDetailRepairmanVO repairmanVO:repairmanVOList){
                            if(user.get("id").toString().equals(repairmanVO.getUId())){
                                iterator.remove();
                                // 同步删除数据库里的数据
                                Map<String,Object> deleteMap = new HashMap<>();
                                deleteMap.put("order_id",repairmanVO.getOrderId());
                                deleteMap.put("u_id",repairmanVO.getUId());
                                repairmanDao.deleteByMap(deleteMap);
                                break;
                            }
                        }
                    }


                }
            }


            if(userList.size()< 1){
                return "";
            }

            // 工单的维修点在修工的区域范围内
            String area = "";
            if (orderInfoMap.get("area") == null) {
                return "";
            }

            area = orderInfoMap.get("area").toString();
            // 区域匹配
            Map<String,Object>  areaMatchUserMap = new HashMap<>();
            List<String>  areaMatchUserList = new ArrayList<>();

            for (Map<String, Object> user : userList) {
                String[] regionNumbers =  appService.getPrecinctRegionNumbers(user.get("id").toString(),user.get("s_id").toString());
                if(Arrays.asList(regionNumbers).contains(area)){
                    areaMatchUserMap.put(user.get("id").toString(),user);
                    areaMatchUserList.add(user.get("id").toString());
                }
            }

            // 如果区域匹配
            if(areaMatchUserMap.size()>0){

                // 如果只有一个匹配的就返回userId
                if(areaMatchUserMap.size() == 1){
                    return areaMatchUserMap.keySet().toArray()[0].toString();
                }else{
                    // 多个匹配，优先工单量少（修工私人池的总单量，包括修工正在处理的也算）
                    // 查找每个用户的工单量，优先最少的
                    Map<String,Object> userOrderNums = getUserOrderNumMap(areaMatchUserList,searchRoleId);

                    // 比较多个订单数,获取最少的单数的userId数组
                    String[] minUserIds =  FunUtil.getMapKeysWithMinValue(userOrderNums);

                    if(minUserIds.length==1){
                        return minUserIds[0];
                    }else{

                       // 多个工单量一样少的 匹配距离近的（修工离维修点的距离）,这里匹配最少单数的几个用户
                        Map<String,Object> distanceMap = new HashMap<>();
//                        for(Map.Entry<String,Object> entry:userOrderNums.entrySet()){
                        for(String userId:minUserIds){

//                            String userId =  entry.getKey();
                            Double distance = 0.0;
                            for (Map<String, Object> user : userList) {
                                if(user.get("id").toString().equals(userId)){
                                    if(user.get("last_lon")!=null && user.get("last_lat")!=null && orderInfoMap.get("longitude")!=null && orderInfoMap.get("latitude")!=null){
                                        distance =  FunUtil.getDistance(Double.parseDouble(user.get("last_lon").toString()),
                                                Double.parseDouble(user.get("last_lat").toString()),
                                                Double.parseDouble(orderInfoMap.get("longitude").toString()),
                                                Double.parseDouble(orderInfoMap.get("latitude").toString()));
                                    }
                                }
                            }

                            distanceMap.put(userId,distance);
                        }

                        // 最近的距离
                        String[] nearestUsers =  FunUtil.getMapKeysWithMinValue(distanceMap);
                        if(nearestUsers.length == 1){
                            return nearestUsers[0];
                        }else{
                            // 实际上应该没有那么数据会到这里,匹配度高（工单的“故障类型”和修工的“擅长类型”）
                            // 故障匹配度
                            Map<String,Object>  matchUserMap = new HashMap<>();

                            // 获取人员的擅长
                            for (Map<String, Object> user : userList) {

                                // 获取过滤后的用户的擅长
                                int minUser = 0;
                                for (String userId:minUserIds){
                                    if(userId.equals(user.get("id").toString())){
                                        minUser = 1;
                                    }
                                }
                                if(minUser == 0){
                                    continue;
                                }

                                if (user.get("goodatdic_id") == null || user.get("goodatdic_id") == "") {
                                    continue;
                                }

                                String userId = user.get("id").toString();
                                String goodatdicId = user.get("goodatdic_id").toString();

                                if(StringUtil.isNotBlank(goodatdicId)){

                                    String[] goodatdicArray = StringUtil.split(goodatdicId, ",");

                                    // 匹配程度
                                    Integer matchDegree = 0;

                                    // 获取工单的故障类型,这里有多个
                                    // 根据order_id查询错误信息,工单故障错误与擅长匹配
                                    List<Map<String, Object>> orderFaultList = kFOrderDao.getOrderFaultByOrderId(reqMap);
                                    if (orderFaultList.size() > 0) {
                                        for (Map<String, Object> fault : orderFaultList) {
                                            for (String goodat : goodatdicArray) {
                                                if (goodat.equals(fault.get("parent_id"))) {
                                                    // 匹配上匹配度+1
                                                    matchDegree++;
                                                }
                                            }
                                        }
                                    }

                                    matchUserMap.put(userId, matchDegree);
                                }

                            }

                            if(matchUserMap.size()!=0){
                                return FunUtil.getMapKeyWithMinValue(matchUserMap);
                            }else{
                                // 没匹配上就随机
                                int rand =  RandomUtil.randomInt(0,nearestUsers.length-1);
                                return nearestUsers[rand];
                            }

                        }
                    }
                }
            }else{
                // 区域不匹配，按最少单量
                List<String> userIdList = userList.stream().map(user->user.get("id").toString()).collect(Collectors.toList());
                Map<String,Object> userOrderNums = getUserOrderNumMap(userIdList,searchRoleId);
                return FunUtil.getMapKeyWithMinValue(userOrderNums);
            }
        }else{
            return "";
        }
    }

    /**
     * 自动分配仓库
     * @param reqMap
     */
    @Override
    public void autoOrderWareHouse(Map<String, Object> reqMap){

        // 当一个工单的维修点在一个或多个仓库归属范围内，哪个仓库离维修点最近，分配给该仓库
        // 获取工单的维修点和仓库的管辖范围
        // 根据工单id查询工单信息
        Map<String, Object> orderInfoMap = appDao.findOrderInfoById(reqMap);
        String area = "";
        if(orderInfoMap.get("area")!=null){
            area = orderInfoMap.get("area").toString();
        }

        // 所有仓库
        // 区域匹配
        Map<String,Object>  matchAreaMap = new HashMap<>();
        List<String> matchWarehouseIdList = new ArrayList<>();
        Map<String,Object> warehouseLocationMap = new HashMap<>();
        warehouseLocationMap.put("deleteFlag","0");
        List<TSSsWarehouselocationVO> warehouseLocationList = warehouseLocationDao.findByCondition(warehouseLocationMap);
        if(warehouseLocationList.size()>0){
            for(TSSsWarehouselocationVO warehouseLocation: warehouseLocationList){

                // 仓库的管辖范围
                Map<String,Object> warehouseRegionMap = new HashMap<>();
                warehouseRegionMap.put("warehouseId",warehouseLocation.getId());
                List<TSSsWarehouseRegionVO> warehouseRegionList = warehouseRegionDao.findByCondition(warehouseRegionMap);
                if(warehouseRegionList.size()>0){
                    for(TSSsWarehouseRegionVO item:warehouseRegionList){
                        // 匹配工单的维修点是否与仓库的管理范围匹配
                        if(Objects.equals(item.getAreaNumber(), area)){
                            matchWarehouseIdList.add(item.getWarehouseId());
                        }
                    }
                }
            }
        }

        if(matchWarehouseIdList.size()>0){

            // 如果匹配到只有一个，分配该仓库
            if(matchWarehouseIdList.size() == 1){

                // 分配该仓库
                Map warehouseIdMap = new HashMap();
                warehouseIdMap.put("order_id",reqMap.get("order_id"));
                warehouseIdMap.put("warehouselocation_id",matchWarehouseIdList.get(0));

                kFOrderDao.updateOrderInfo(warehouseIdMap);
            }else{

                // 如果匹配到多个，计算每个仓库到维修点的距离,最小距离仓库匹配，有多个最小距离就随机
                Map<String,Object> warehouseDisMap = new HashMap<>();
                for(String warehouseId:matchWarehouseIdList){
                    // 订单经纬度和仓库的经纬度之间的距离
                    String orderLon = orderInfoMap.get("longitude").toString();
                    String orderLat = orderInfoMap.get("latitude").toString();
                    String warehouseLon = "";
                    String warehouseLat = "";

                    // 仓库经纬度
                    for(TSSsWarehouselocationVO warehouseLocation: warehouseLocationList){
                        if(warehouseId.equals(warehouseLocation.getId().toString())){
                            warehouseLon = warehouseLocation.getWarehouseLong();
                            warehouseLat = warehouseLocation.getWarehouseLat();
                        }
                    }

                    Double distance =  FunUtil.getDistance(Double.parseDouble(orderLon), Double.parseDouble(orderLat),Double.parseDouble(warehouseLon),Double.parseDouble(warehouseLat));

                    warehouseDisMap.put(warehouseId,(int)Math.floor(distance));

                }

                String nearestWarehouseId =  FunUtil.getMapKeyWithMinValue(warehouseDisMap);


                // 分配该仓库
                Map warehouseIdMap = new HashMap();
                warehouseIdMap.put("order_id",reqMap.get("order_id"));
                warehouseIdMap.put("warehouselocation_id",nearestWarehouseId);

                kFOrderDao.updateOrderInfo(warehouseIdMap);
            }

        }else{
            // 当一个工单的维修点不在任何仓库范围内，哪个仓库离维修点最近，分配给该仓库；有两个甚至多个仓库到维修点距离一样，采取随机分配原则
            // 仓库经纬度
            Map<String,Object> warehouseDisMap = new HashMap<>();

            // 订单没有经纬度，就随机返回一个仓库
            String nearestWarehouseId = "";
            if(orderInfoMap.get("longitude")==null || orderInfoMap.get("latitude")==null){
                int rand = RandomUtil.randomInt(0,warehouseLocationList.size()-1);
                nearestWarehouseId =  warehouseLocationList.get(rand).getId();
            }else{
                for(TSSsWarehouselocationVO warehouseLocation: warehouseLocationList){

                    String orderLon = orderInfoMap.get("longitude").toString();
                    String orderLat = orderInfoMap.get("latitude").toString();
                    String warehouseLon = warehouseLocation.getWarehouseLong();
                    String warehouseLat = warehouseLocation.getWarehouseLat();

                    Double distance =  FunUtil.getDistance(Double.parseDouble(orderLon), Double.parseDouble(orderLat),Double.parseDouble(warehouseLon),Double.parseDouble(warehouseLat));

                    warehouseDisMap.put(warehouseLocation.getId().toString(),(int)Math.floor(distance));
                }

                nearestWarehouseId =  FunUtil.getMapKeyWithMinValue(warehouseDisMap);
            }


            // 分配该仓库
            Map warehouseIdMap = new HashMap();
            warehouseIdMap.put("order_id",reqMap.get("order_id"));
            warehouseIdMap.put("warehouselocation_id",nearestWarehouseId);

            kFOrderDao.updateOrderInfo(warehouseIdMap);
        }

    }



    /**
     * 获取用户列表中工单量最少的用户id,如果有多个最少，随机取一个
     * @param userIdArr
     * @return
     */
    public String getMinOrderUserId(String[] userIdArr,String roleId){

        Map<String,Object> matchUserOrderNumMap = new HashMap<>();
        Map<String,Object> countMap = new HashMap<>();
        countMap.put("roleId",roleId);

        for (String userId:userIdArr){
            countMap.put("userId",userId);
            Integer orderNum = kFOrderDao.getCountByRoleIdUserId(countMap);
            matchUserOrderNumMap.put(userId,orderNum);
        }

        // 工单量最少返回
        return FunUtil.getMapKeyWithMinValue(matchUserOrderNumMap);
    }


    /**
     * 获取用户列表的工单量
     * @param userIdArr
     * @return
     */
    public Map<String,Object> getUserOrderNumMap(List<String> userIdArr, String roleId){

        Map<String,Object> matchUserOrderNumMap = new HashMap<>();
        Map<String,Object> countMap = new HashMap<>();
        countMap.put("roleId",roleId);

        for (String userId:userIdArr){
            countMap.put("userId",userId);
            Integer orderNum = 0;
            if(roleId.equals(Constants.ROLE_TZ)){
                orderNum = kFOrderDao.getCountByRoleIdUserId(countMap);
            }else{
                orderNum = kFOrderDao.getCountByXgUserId(countMap);
            }
            matchUserOrderNumMap.put(userId,orderNum);
        }

        return matchUserOrderNumMap;
    }


    @Override
    public int updateOrderInfo(Map<String, Object> reqMap) {
        // 封装一个推送的map
        Map<String, Object> msgMap = new HashMap<>();
        Map<String, String> strMap = new HashMap<>();
        String orderId = reqMap.get("order_id").toString();
        Map<String, Object> order = appDao.getOrderInfoById(orderId);
        int result = 0;
        // 根据工单id查询工单信息
        Map<String, Object> orderInfoMap = appDao.findOrderInfoById(reqMap);
        String orderEndNumber = getOrderNoEndNumber(orderInfoMap.get("order_no").toString());

        // 1车主确认
        result += kFOrderDao.updateOrderInfo(reqMap);

        // 判断客服是否受理完成, --》转诊？
        if (reqMap.containsKey("order_status") && reqMap.get("order_status") != null
                && Integer.valueOf(reqMap.get("order_status").toString()) == Constants.ORDER_STATUS_DTZ) {
            cachedThreadPool.execute(() -> {
                // 客服受理完成将工单推送给选择的听诊
                reqMap.put("alias", reqMap.get("u_t_id"));

                reqMap.put("msg", String.format(PushConstants.TEMPLATE_ORDER_KF_ACCEPTED, orderEndNumber));

                reqMap.put("type", "3");
                reqMap.put("code", "10000");
                //webSocketPushUtil.websocketPush(reqMap, reqMap.get("u_t_id").toString());
                jiGuangPushUtil.push(reqMap);
            });
            try {
                //修工指派听诊 进行绩效考核
                OrderCheck checkByOrderId = orderService.selectCheckByOrderId(reqMap.get("order_id").toString(),
                        reqMap.get("u_s_id").toString(),Constants.ORDER_CHECK_KF_RESPONSE);
                if (checkByOrderId!=null&&checkByOrderId.getEndTime()==null){
                    orderService.updateKfEndTimeList(checkByOrderId.getId());
                }
                String uId = reqMap.get("u_s_id").toString();
                OrderCheck checkByOrderId1 = orderService.selectCheckByOrderId(reqMap.get("order_id").toString(), uId,
                        Constants.ORDER_CHECK_KF_RESPONSE);
                if(checkByOrderId1 != null) {
                    orderService.updateKfByOrderId(OrderCheck.builder()
                            .id(checkByOrderId1.getId())
                            .orderId(reqMap.get("order_id").toString())
                            .isTakeOrder(1)
                            .build());
                }
                //插入听诊绩效考核
                String tId = reqMap.get("u_t_id").toString();
                orderService.insertTzOrderCheck(OrderCheck.builder()
                        .orderId(reqMap.get("order_id").toString())
                        .orderNo(orderInfoMap.get("order_no").toString())
                        .userId(tId)
                        .roleType(Constants.ROLE_TZ)
                        .orderCreateTime(Orgin.getDateTime(orderInfoMap,"create_time"))
                        .checkType(Constants.ORDER_CHECK_TZ_RESPONSE)
                        .build());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        // 判断是否听诊完成 --》推送给修工，仓储？
        if (reqMap.containsKey("order_status") && reqMap.get("order_status") != null
                && Integer.valueOf(reqMap.get("order_status").toString()) == Constants.ORDER_STATUS_PJ) {
            // 听诊完成将工单推送给选择的修工
            List<Map<String, Object>> repairmanList = (List<Map<String, Object>>) reqMap.get("repairmanInfo");
            msgMap.put("msg", String.format(PushConstants.TEMPLATE_ORDER_TZ_OVER_XG_ACCEPT_ACCESSORIES, orderEndNumber));
            // 推送给修工
            for (Map<String, Object> map : repairmanList) {
                if(map.get("u_id") != null) {
                    reqMap.put("alias", map.get("u_id"));
                    reqMap.put("msg", msgMap.get("msg"));
                    reqMap.put("type", 5);
                    jiGuangPushUtil.push(reqMap);
                }
            }
            // 某个订单的听诊
            msgMap.put("msg", "听诊已经结束,请尽快配料!");
            reqMap.put("msg", msgMap.get("msg"));
            // 推送给仓管
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("r_id", "4");
            queryMap.put("s_id", reqMap.get("s_id"));
            // 这里修改成只推送给分配的仓库的仓管
//            List<Map<String, Object>> cgList = appDao.findUserRoleByRid(queryMap);
            List<TSSsUserVO> cgList = tsSsUserService.listCgByOrderId(orderId);

            try {
                //更新听诊响应时间
                OrderCheck checkByOrderId = orderService.selectCheckByOrderId(orderId,
                        reqMap.get("current_user_id").toString(),Constants.ORDER_CHECK_TZ_RESPONSE);
                if (checkByOrderId!=null&&checkByOrderId.getEndTime()==null){
                    if(orderService.isCheckTypeExist(checkByOrderId.getOrderId(),checkByOrderId.getUserId(),Constants.ORDER_CHECK_TZ_FINISH) == 0){
                        orderService.updateKfEndTimeList(checkByOrderId.getId());
                        //插入及时听诊数据
                        orderService.insertTzOrderCheck(OrderCheck.builder()
                                .orderId(checkByOrderId.getOrderId())
                                .orderNo(checkByOrderId.getOrderNo())
                                .userId(checkByOrderId.getUserId())
                                .roleType(Constants.ROLE_TZ)
                                .orderCreateTime(checkByOrderId.getOrderCreateTime())
                                .checkType(Constants.ORDER_CHECK_TZ_FINISH)
                                .build());
                    }
                }

                OrderCheck checkByOrderId1 = orderService.selectCheckByOrderId(orderId,
                        reqMap.get("current_user_id").toString(), Constants.ORDER_CHECK_TZ_FINISH);
                orderService.updateKfEndTimeList(checkByOrderId1.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 过滤所有符合区域的仓管，并求出所有仓管的id
            cgList.forEach(item -> {
                reqMap.put("type", "5");
                reqMap.put("msg", String.format(PushConstants.TEMPLATE_ORDER_TZ_OVER_CG_ACCESSORIES, orderEndNumber));
                reqMap.put("code", "10000");
                webSocketPushUtil.websocketPush(reqMap, item.getId());
                try {
                    //插入仓管审核
                    if(orderService.isCheckTypeExist(orderId, item.getId(),Constants.ORDER_CHECK_CG_RESPONSE) == 0) {
                        orderService.insertTzOrderCheck(OrderCheck.builder()
                                .orderId(orderId)
                                .orderNo(order.get("order_no").toString())
                                .userId(item.getId())
                                .roleType(Constants.ROLE_CG)
                                .orderCreateTime(orderService.stringConvertDate(order.get("create_time").toString()))
                                .checkType(Constants.ORDER_CHECK_CG_RESPONSE)
                                .build());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        Map<String, Object> userInfoMap = (Map<String, Object>) reqMap.get("user_info");// 移动端携带的用户信息

        // 2.判断是否工单流转
        if (reqMap.get("order_status") != null && !reqMap.get("order_status").equals("")) {
            // 根据总工单id删除状态比当前状态大的工单明细
            kFOrderDao.updateOrderDetail(reqMap);
            // 创建工单明细
            reqMap.put("order_detail_id", UuidUtil.get32UUID());
            result += kFOrderDao.createOrderDetail(reqMap);
        }
        // 3.判断是否有维修工信息 (听诊进行听诊操作)
        if (reqMap.get("repairmanInfo") != null && !reqMap.get("repairmanInfo").equals("")) {
            List<Map<String, Object>> repairmanList = (List<Map<String, Object>>) reqMap.get("repairmanInfo");
            for (Map<String, Object> repairmanMap : repairmanList) {
                repairmanMap.put("current_user_id", reqMap.get("current_user_id"));
                repairmanMap.put("order_id", reqMap.get("order_id"));
                if (repairmanMap.get("check_status") != null && !repairmanMap.get("check_status").equals("")) {
                    kFOrderDao.updateRepairman(repairmanMap);
                } else {
                    repairmanMap.put("repairman_id", UuidUtil.get32UUID());
                    // 添加工单的维修工
                    result += kFOrderDao.createRepairman(repairmanMap);
                }
            }
        }

        // 4.判断是否有保养配件 (客服进行选择配件操作)
        if (reqMap.get("upkeepParts") != null && !reqMap.get("upkeepParts").equals("")) {
            // 根据订单id 清空原始保养配件
            reqMap.put("p_type", 2);

            kFOrderDao.deleteOrderParts(reqMap);
            List<Map<String, Object>> upkeepPartsList = (List<Map<String, Object>>) reqMap.get("upkeepParts");
            for (Map<String, Object> upkeepPartsMap : upkeepPartsList) {
                upkeepPartsMap.put("orderParts_id", UuidUtil.get32UUID());
                upkeepPartsMap.put("s_id", reqMap.get("s_id"));
                upkeepPartsMap.put("order_id", reqMap.get("order_id"));
                upkeepPartsMap.put("p_type", 2);// 保养配件为2change_flag
                upkeepPartsMap.put("change_flag", 0);
                upkeepPartsMap.put("current_user_id", reqMap.get("current_user_id"));
                // 添加配件
                result += kFOrderDao.createOrderParts(upkeepPartsMap);
            }
        }
        // 5.判断是否有维修配件 (客服进行选择配件操作)
        if (reqMap.get("repairParts") != null && !reqMap.get("repairParts").equals("")) {
            // 根据订单id 清空原始维修配件
            reqMap.put("p_type", 1);
            kFOrderDao.deleteOrderParts(reqMap);
            List<Map<String, Object>> repairPartsList = (List<Map<String, Object>>) reqMap.get("repairParts");
            for (Map<String, Object> repairPartsMap : repairPartsList) {
                repairPartsMap.put("orderParts_id", UuidUtil.get32UUID());
                repairPartsMap.put("s_id", reqMap.get("s_id"));
                repairPartsMap.put("order_id", reqMap.get("order_id"));
                repairPartsMap.put("p_type", 1);// 维修配件为1
                repairPartsMap.put("change_flag", 0);
                repairPartsMap.put("current_user_id", reqMap.get("current_user_id"));
                // 添加配件
                result += kFOrderDao.createOrderParts(repairPartsMap);
            }
        }

        // 6判断是否为仓管进行 确认配件操作 是则将增减配件状态的配件delete_flag设为2 6待领料
        if (reqMap.get("order_status") != null
                && Integer.parseInt(reqMap.get("order_status").toString()) == Constants.ORDER_STATUS_DLL) {
            kFOrderDao.updateOrderParts(reqMap);
        }

        // 7判断是否为客户评价操作 是则 将判断评价总分是否<=7 是则插入投诉处理记录 18.已完成
        if (reqMap.get("order_status") != null
                && Integer.parseInt(reqMap.get("order_status").toString()) == Constants.ORDER_STATUS_WC) {
            int appraise_account = 0;
            if (reqMap.get("appraise_manner") != null) {
                appraise_account += Integer.parseInt(reqMap.get("appraise_manner").toString());
            }
            if (reqMap.get("appraise_result") != null) {
                appraise_account += Integer.parseInt(reqMap.get("appraise_result").toString());
            }
            if (reqMap.get("appraise_productivity") != null) {
                appraise_account += Integer.parseInt(reqMap.get("appraise_productivity").toString());
            }
            // 评价总和低于标准 添加投诉处理记录
            if (appraise_account <= myConfig.getAPPRAISE_ACCOUNT()) {
                HashMap<String, Object> complaintHandleMap = new HashMap<String, Object>();
                complaintHandleMap.put("id", UuidUtil.get32UUID());
                complaintHandleMap.put("order_id", reqMap.get("order_id"));
                complaintHandleMap.put("s_id", reqMap.get("s_id"));
                complaintHandleMap.put("current_user_id", userInfoMap.get("id"));
                result += kFOrderDao.insertComplaintHandle(complaintHandleMap);
            }

            // TODO 客服已听诊操作 || 仓管确认配件操作要更新工单_配件中的客服||仓管操作标识
        }

        if (reqMap.containsKey("order_status")) {

            // 更新工单超时推送
            reqMap.put("user_id",reqMap.get("current_user_id"));
            appDao.updateOrderTimeoutPush(reqMap);
        }

        // 听诊新增建议
        if(reqMap.containsKey("tz_advice")){

            Map<String,Object> tzAdviceMap = new HashMap<>();
            tzAdviceMap.put("order_id",reqMap.get("order_id"));
            tzAdviceMap.put("tz_advice",reqMap.get("tz_advice"));

            appDao.updateOrderInfo(tzAdviceMap);
        }

        return result;
    }

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getOrderInfo(Map<String, Object> reqMap) {

        // 1.根据工单id获取总工单信息
        Map<String, Object> orderMap = kFOrderDao.getOrderInfoByOrderId(reqMap);

        // 2.根据order_id 获取关联故障信息
        List<Map<String, Object>> orderFaultList = kFOrderDao.getOrderFaultByOrderId(reqMap);
        orderMap.put("faultInfo", orderFaultList);// fault_id fault_name

        // 3.根据order_id 获取关联修工信息
        List<Map<String, Object>> orderRepairmanList = kFOrderDao.getOrderRepairmanByOrderId(reqMap);
        orderMap.put("repairmanInfo", orderRepairmanList);// repairman_id repairman_name repairman_type check_status
        // check_time

        // 4判断是否需要增减配件
        // as_status=2 需要增减配件 :表示工单是从修工流传回来的 需要查询以下数据
        // 1.原始保养配件 2.原始维修配件 3.增减的配件
        if (orderMap.get("as_status") != null && orderMap.get("as_status").equals(2)) {
            // 如果工单是保养 或者保养+维修则要原始保养配件
            if (orderMap.get("order_type") != null && orderMap.get("order_type").equals(2)
                    || orderMap.get("order_type").equals(3)) {
                // 获取原始保养配件
                reqMap.put("change_flags", new int[]{0});
                reqMap.put("p_type", 2);
                List<Map<String, Object>> upkeepParts = kFOrderDao.getPartsByCondition(reqMap);
                orderMap.put("upkeepParts", upkeepParts);
            }
            // 获取原始维修配件
            reqMap.put("p_type", 1);
            List<Map<String, Object>> repairParts = kFOrderDao.getPartsByCondition(reqMap);
            orderMap.put("repairParts", repairParts);

            // 获取增减的配件
            reqMap.put("change_flags", new int[]{1, 2});
            reqMap.put("p_type", null);
            List<Map<String, Object>> changeParts = kFOrderDao.getPartsByCondition(reqMap);
            orderMap.put("changeParts", changeParts);

        } else // 不需要增减配件 说明工单时从听诊流转过来的 只需根据m_id 查询保养配件信息
        {
            if (orderMap.get("m_id") != null && !orderMap.get("m_id").equals("")) {
                reqMap.put("m_id", orderMap.get("m_id"));
                List<Map<String, Object>> upkeepInfo = kFOrderDao.getUpkeepInfoByMId(reqMap);
                orderMap.put("upkeepParts", upkeepInfo);// parts_id quantity dictionaries_name dictionaries_model
                // dictionaries_unit dictionaries_price
            }
        }
        return orderMap;
    }

    @Override
    public Map<String, Object> complaintHandleList(Map<String, Object> reqMap) {
        // 1.设置分页的limit和offset
        Map<String, Object> pageMap = Page.appPage(reqMap.get("pageSize").toString(),
                reqMap.get("currentPage").toString());
        reqMap.put("pageSize", pageMap.get("limit"));
        reqMap.put("currentPage", pageMap.get("offset"));
        int limit = Integer.valueOf(pageMap.get("limit").toString());
        // 2.查询总记录数
        int total = kFOrderDao.countComplaintHandle(reqMap);

        // 3执行分页查询
        List<Map<String, Object>> orderList = kFOrderDao.listComplaintHandle(reqMap);

        // 4 根据工单id关联查询修工信息
        if (total > 0) {
            for (Map<String, Object> orderMap : orderList) {
                List<Map<String, Object>> repairmanList = kFOrderDao.getOrderRepairmanByOrderId(orderMap);
                orderMap.put("repairmanInfo", repairmanList);
            }
        }

        // 5包装结果集 总条数 总页数 数据集
        HashMap<String, Object> resultMap = new HashMap<String, Object>();
        int pages = (total + limit - 1) / limit;// 总页数 需要有余进一

        resultMap.put("total", total);
        resultMap.put("pages", pages);
        resultMap.put("list", orderList);
        return resultMap;
    }

    @Override
    public Map<String, Object> getComplaintHandleInfoByOrder_id(Map<String, Object> reqMap) {
        // 1.获取投诉工单详情 关联到服务人员及车辆信息
        Map<String, Object> complaintHandleInfo = kFOrderDao.getComplaintHandleInfo(reqMap);

        // 2.根据order_id 获取关联故障信息
        List<Map<String, Object>> orderFaultList = kFOrderDao.getOrderFaultByOrderId(reqMap);
        complaintHandleInfo.put("faultInfo", orderFaultList);// fault_id fault_name

        // 3.根据order_id 获取关联修工信息
        List<Map<String, Object>> orderRepairmanList = kFOrderDao.getOrderRepairmanByOrderId(reqMap);
        complaintHandleInfo.put("repairmanInfo", orderRepairmanList);// repairman_id repairman_name repairman_type
        // check_status check_time
        return complaintHandleInfo;
    }

    @Override
    public int updateComplaint_handle(Map<String, Object> reqMap) {
        // 设置handle_status 为已处理
        reqMap.put("handle_status", 2);
        return kFOrderDao.updateComplaint_handle(reqMap);
    }

    @Override
    public List<Map<String, Object>> readExcel(MultipartFile file) throws MyException {
        // 获取文件的名字
        String originalFilename = file.getOriginalFilename();
        Workbook workbook = null;
        // 错误信息接收器
        String errorMsg = null;
        List<Map<String, Object>> partsList = new ArrayList<Map<String, Object>>();
        try {
            if (originalFilename.endsWith(".xls")) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else if (originalFilename.endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(file.getInputStream());
            }
        } catch (Exception e) {
            logger.info(originalFilename);
            e.printStackTrace();
            throw new MyException(-1, "格式错误");
        }
        if (workbook == null) {
            logger.info(originalFilename);
            throw new MyException(-1, "格式错误");
        } else {
            // 获取所有的工作表的的数量
            int numOfSheet = workbook.getNumberOfSheets();
            String br = "<br/>";
            // 遍历这个这些表
            for (int i = 0; i < numOfSheet; i++) {
                String sheetName = workbook.getSheetName(i);
                if (sheetName.contains("维修")) {
                    sheetName = "repair";
                } else if (sheetName.contains("保养")) {
                    sheetName = "upkeep";
                } else if (sheetName.contains("新增")) {
                    sheetName = "xinzeng";
                } else if (sheetName.contains("追加")) {
                    sheetName = "zhuijia";
                } else if (sheetName.contains("返仓")) {
                    sheetName = "fancang";
                }
                List<Map<String, Object>> partsListOfSheet = new ArrayList<Map<String, Object>>();
                Map<String, Object> partsOfSheetMap = new HashMap<String, Object>();
                // 获取一个sheet也就是一个工作簿
                Sheet sheet = workbook.getSheetAt(i);
                // 获取总行数
                int lastRowNum = sheet.getLastRowNum();
                // 从第一行开始第一行一般是标题
                for (int r = 1; r <= lastRowNum; r++) {
                    Map<String, Object> partsMap = new HashMap<String, Object>();
                    Row row = sheet.getRow(r);
                    if (row == null) {
                        errorMsg += br + "第" + r + "行数据有问题，请仔细检查！";
                        continue;
                    }
                    if (row.getCell(0) != null) {
                        String cell0 = null;
                        try {
                            cell0 = String.valueOf((int) row.getCell(0).getNumericCellValue());
                        } catch (Exception e) {
                            cell0 = String.valueOf(row.getCell(0).getStringCellValue());
                        }
                        if (cell0.equals("0")) {
                            break;
                        }
                    }
                    if (row.getCell(1) != null) {
                        String cell1 = null;
                        try {
                            cell1 = row.getCell(1).getStringCellValue();
                        } catch (Exception e) {
                            cell1 = row.getCell(1).getNumericCellValue() + "";
                        }
                        if (cell1 != null && !row.toString().trim().equals("")) {
                            partsMap.put("code", cell1);
                        }
                    }
                    if (row.getCell(2) != null) {
                        String cell2 = null;
                        try {
                            cell2 = row.getCell(2).getStringCellValue();
                        } catch (Exception e) {
                            cell2 = row.getCell(2).getNumericCellValue() + "";
                        }
                        if (cell2 != null && !row.toString().trim().equals("")) {
                            partsMap.put("dictionaries_name", cell2);
                        }
                    }
                    if (row.getCell(3) != null) {
                        Double cell3 = null;
                        try {
                            cell3 = (Double) row.getCell(3).getNumericCellValue();
                        } catch (Exception e) {
                            cell3 = Double.valueOf(row.getCell(3).getStringCellValue());
                        }
                        partsMap.put("quantity", cell3);
                    }
                    if (row.getCell(4) != null && !row.toString().trim().equals("")) {
                        partsMap.put("price", String.valueOf(row.getCell(4)));
                    }
                    if (row.getCell(5) != null) {
                        String cell5 = null;
                        try {
                            cell5 = row.getCell(5).getStringCellValue();
                        } catch (Exception e) {
                            cell5 = row.getCell(5).getNumericCellValue() + "";
                        }
                        if (cell5 != null && !row.toString().trim().equals("")) {
                            partsMap.put("dictionaries_unit", cell5);
                        }
                    }
                    if (row.getCell(6) != null) {
                        String cell6 = null;
                        try {
                            cell6 = row.getCell(6).getStringCellValue();
                        } catch (Exception e) {
                            cell6 = row.getCell(6).getNumericCellValue() + "";
                        }
                        if (cell6 != null && !row.toString().trim().equals("")) {
                            partsMap.put("dictionaries_format", cell6);
                        }
                    }
                    if (row.getCell(7) != null) {
                        String cell7 = null;
                        try {
                            cell7 = row.getCell(7).getStringCellValue();
                        } catch (Exception e) {
                            cell7 = row.getCell(7).getNumericCellValue() + "";
                        }
                        if (cell7 != null && !row.toString().trim().equals("")) {
                            partsMap.put("dictionaries_type", cell7);
                        }
                    }
                    if (row.getCell(8) != null) {
                        String cell8 = null;
                        try {
                            cell8 = row.getCell(8).getStringCellValue();
                        } catch (Exception e) {
                            cell8 = row.getCell(8).getNumericCellValue() + "";
                        }
                        if (cell8 != null && !row.toString().trim().equals("")) {
                            partsMap.put("remark", cell8);
                        }
                    }
                    partsListOfSheet.add(partsMap);
                }
                partsOfSheetMap.put(sheetName, partsListOfSheet);
                partsList.add(partsOfSheetMap);
            }
        }
        return partsList;
    }

    @Override
    public int insertAuthLog(Map<String, Object> map) {

        map.put("id", UuidUtil.get32UUID());

        return kFOrderDao.insertAuthLog(map);
    }

    @Override
    public int updatePartsPrice(String p_id, String price, String discount_price, String order_id) {

        return kFOrderDao.updatePartsPrice(p_id, price, discount_price, order_id);
    }

    @Override
    public Map<String, Object> getDiscountOrderList(Map<String, Object> reqMap) {
        // 1.设置分页的limit和offset
        Map<String, Object> pageMap = Page.appPage(reqMap.get("pageSize").toString(),
                reqMap.get("currentPage").toString());
        reqMap.put("pageSize", pageMap.get("limit"));
        reqMap.put("currentPage", pageMap.get("offset"));
        // 2.查询总记录数
        int total = kFOrderDao.getCountByDiscountOrder(reqMap);
        List<Map<String, Object>> orderList = kFOrderDao.getDiscountOrderList(reqMap);

        if (total > 0) {
            orderList.forEach(orderMap -> {
                orderMap.put("order_id", orderMap.get("id"));
                orderMap.put("repairmanInfo", kFOrderDao.getOrderRepairmanByOrderId(orderMap));
                orderMap.put("tzInfo", kFOrderDao.getTzInfoByOrderId(orderMap.get("order_id").toString()));
                // 查询订单的故障类型
                List<Map<String, Object>> nameBy = kFOrderDao.getDictionariesNameBy(orderMap);
                List<Map<String, Object>> mapList =
                        toolViewBoardService.listByFault(nameBy, reqMap.get("s_id").toString());
                orderMap.put("dictionaries_nameList",mapList);
            });
        }
        Map<String, Object> orderObject = new HashMap<>();
        orderObject.put("total", total);
        orderObject.put("orderList",orderList);
        return orderObject;

    }

    @Override
    public Map<String, Object> getDiscountOrderListByParts(String parts, String order_id) {

        return kFOrderDao.getDiscountOrderListByParts(parts, order_id);
    }

    @Override
    public int handleFlag(Map<String, Object> resultMap) {

        return kFOrderDao.handleFlag(resultMap);
    }

    @Override
    public List<Map<String, Object>> getOrderDetail(String order_id) {
        return kFOrderDao.getOrderDetail(order_id);
    }

    @Override
    public List<Map<String, Object>> getOrderPartsDetail(String order_id) {
        return kFOrderDao.getOrderPartsDetail(order_id);
    }

    @Override
    public List<Map<String, Object>> getDiscountOrderInfo(String order_id) {
        List<Map<String, Object>> list = kFOrderDao.getDiscountOrderInfo();
        // 根据工单id查询听诊的信息
        Map<String, Object> tzInfoMapList = kFOrderDao.getTzInfoByOrderId(order_id);
        // 根据order_id查询修工的信息
        List<Map<String, Object>> xgInfoMapList = kFOrderDao.getXgInfoByOrderId(order_id);
        List<Map<String, Object>> resultList = list.stream().map(map -> {

            map.put("tzInfo", tzInfoMapList);
            map.put("xgInfo", xgInfoMapList);
            return map;

        }).collect(Collectors.toCollection(ArrayList::new));

        return resultList;
    }

    @Override
    public Map<String, Object> getGgDiscountOrderList(Map<String, Object> reqMap) {

        // 1.设置分页的limit和offset
        Map<String, Object> pageMap = Page.appPage(reqMap.get("pageSize").toString(),
                reqMap.get("currentPage").toString());
        reqMap.put("pageSize", pageMap.get("limit"));
        reqMap.put("currentPage", pageMap.get("offset"));
        int total = kFOrderDao.getCountByDiscountOrder(reqMap);
        List<Map<String, Object>> orderList = kFOrderDao.getGgDiscountOrderList(reqMap);

        orderList.forEach(orderMap -> {
            orderMap.put("order_id", orderMap.get("id"));
            orderMap.put("repairmanInfo", kFOrderDao.getOrderRepairmanByOrderId(orderMap));
            orderMap.put("tzInfo", kFOrderDao.getTzInfoByOrderId(orderMap.get("order_id").toString()));
        });

        Map<String, Object> orderObject = new HashMap<>();
        orderObject.put("total", total);
        orderObject.put("orderList",orderList);
        return orderObject;
    }

    @Override
    public List<Map<String, Object>> getOrderInfoByOrderId(String order_id) {

        return kFOrderDao.getOrderInfoAndContactByOrderId(order_id);
    }

    @Override
    public List<Map<String, Object>> findUserByRid(Map<String, Object> reqMap) {
        return kFOrderDao.findUserByRid(reqMap);
    }

    @Override
    public List<String> findXgId(Map<String, Object> reqMap) {
        return kFOrderDao.findXgId(reqMap);
    }

    /**
     * 获取工单配件列表
     */
    @Override
    public Map<String, Object> detailPartsInfo(Map<String, Object> reqMap) {
        // 获取工单详情
        Map<String, Object> orderInfo = kFOrderDao.getOrderInfo(
                StringUtils.isEmpty(reqMap.get("parent_id").toString()) ? reqMap.get("order_id").toString()
                        : reqMap.get("parent_id").toString());
        // 获取配件
        List<Map<String, Object>> orderDetailPartsList = kFOrderDao.getOrderDetailParts(orderInfo.get("id").toString());
        //维修
        List<Map<String, Object>> weixiuList = new ArrayList<Map<String, Object>>();
        //增加
        List<Map<String, Object>>changList = new ArrayList<Map<String, Object>>();
        //保养
        List<Map<String, Object>> baoyangList = new ArrayList<Map<String, Object>>();
        for (Map<String, Object> detailParts : orderDetailPartsList) {
            if ("1".equals(detailParts.get("change_flag").toString()) || "2".equals(detailParts.get("change_flag").toString())) {
                changList.add(detailParts);
            } else {
                if (StringUtils.equals(detailParts.get("p_type").toString(), "1")) {
                    weixiuList.add(detailParts);
                } else {
                    baoyangList.add(detailParts);
                }
            }
        }

        this.processDeparts(weixiuList, changList);
        this.processDeparts(baoyangList, changList);

        //获取当前工单的评价
        Map<String, Object> appraise = kFOrderDao.getOrderInfo(reqMap.get("order_id").toString());
        String[] appraise_lable = {};
        // 分割评价标签
        if ((appraise.get("appraise_lable") != null)) {
            appraise_lable = appraise.get("appraise_lable").toString().split(";");
            appraise.put("appraise_lable", appraise_lable);
        } else {
            appraise.put("appraise_lable", appraise_lable);
        }
        //工单维护保养状态
        appraise.put("order_type", orderInfo.get("order_type"));
        //配件list
        appraise.put("weixiuList", weixiuList);
        appraise.put("baoyangList", baoyangList);
        //获取工单节点
        List<Map<String, Object>> orderDetal = kFOrderDao.getOrderDetalInfo(reqMap.get("order_id").toString());
        //封装工单状态名称
        List<String> orderStatusList = new LinkedList<String>();
        ;
        for (Map<String, Object> detalName : orderDetal) {
            String name = "";
            switch (detalName.get("order_status").toString()) {
                case "1":
                    name = "司机提交工单，等待车主确认";
                    break;
                case "2":
                    name = "等待客服受理";
                    break;
                case "3":
                    name = "客服已指派听诊，等待听诊受理";
                    break;
                case "5":
                    name = "等待仓管配件";
                    break;
                case "6":
                    name = "仓管已配件，等待修工领料";
                    break;
                case "7":
                    name = "修工已领料，前往现场";
                    break;
                case "9":
                    name = "修工到达现场";
                    break;
                case "10":
                    name = "车主已经确认维修方案";
                    break;
                case "11":
                    name = "修工自检";
                    break;
                case "12":
                    name = "修工互检";
                    break;
                case "13":
                    name = "修工已维修结束";
                    break;
                case "14":
                    name = "确认结束";
                    break;
                case "15":
                    name = "维修完成，等待车主支付";
                    break;
                case "16":
                    name = "车主现金支付，等待确认收款";
                    break;
                case "17":
                    name = "支付完成，等待车主待评价";
                    break;
                case "18":
                    name = "工单完成";
                    break;
                default:
                    break;
            }
            String timeString = detalName.get("create_time").toString().substring(0, 19);
            String status = name + " " + timeString;
            orderStatusList.add(status);
        }
        appraise.put("orderStatusList", orderStatusList);
        //获取工单履历
        List<Map<String, Object>> ordeList = kFOrderDao.getordeList(appraise);
        appraise.put("lvliList", ordeList);

        return appraise;
    }

    private void processDeparts(List<Map<String, Object>> list, List<Map<String, Object>> changeList){
        if (list.size() > 0 && changeList.size() > 0) {
            for (Map<String, Object> map : list) {
                for (Map<String, Object> cg : changeList) {
                    if (map.get("p_id").toString().equals(cg.get("p_id").toString())) {
                        if ("1".equals(cg.get("change_flag").toString())) {
                            map.put("quantity", (int) map.get("quantity") + (int) cg.get("quantity"));
                        } else {
                            map.put("quantity", (int) map.get("quantity") - (int) cg.get("quantity"));
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<Map<String, Object>> listCarMaster(User currentUser, Map<String, Object> reqMap) {
        List<Map<String, Object>> userList = kFOrderDao.listCarMaster(currentUser.getS_id());
        // 汉语转拼音
        for (Map<String, Object> user : userList) {
            String userName = user.get("user_name").toString();
            StringBuffer pinyin = new StringBuffer();
            StringBuffer pinyinIc = new StringBuffer();
            for (char item : userName.toCharArray()) {
                pinyin.append(PinyinUtil.convertToPinyin(item));
                pinyinIc.append(PinyinUtil.convertToPinyinIc(item));
            }
            user.put("pinyin", pinyin);
            user.put("pinyinIc", pinyinIc);
        }
        return kFOrderDao.listCarMaster(currentUser.getS_id());
    }
}
